<?php
/**
 *	KLF Framework
 *
 *	Written by Kristian Oye <kristianoye@gmail.com> on Dec 18, 2011
 *	Copyright (C) 2010-2011
 */
namespace KLF\System\Web\MVC
{
	use KLF\System\Web\KHttpRequest;
	use KLF\System\Web\KHttpContext;
	use KLF\System\Web\KHttpResponse;
	use KLF\System\Web\Routing\KRouteData;
	use KLF\System\Web\Routing\KRouteContext;
	use KLF\System\Errors\KArgumentException;
	use KLF\System\Web\Routing\KRouteCollection;
	
	/**
	 *  Class KController
	 *
	 *  The MVC controller
	 *
	 *  @package KLF\System\Web\MVC
	 *  @access public
	 *  @author Kristian Oye <kristianoye@gmail.com>
	 *  @since 0.1
	 *
	 *  @method KContoller NewInstance
	 *  
	 *  @property KControllerContext $ControllerContext
	 *  @property KHttpContext $HttpContext The current HTTP context
	 *  @property string $Name
	 *  @property KHttpRequest $Request
	 *  @property KHttpResponse $Response
	 *  @property KRouteCollection $RouteCollection
	 *  @property KRouteData $RouteData
	 *  @property \KLF\System\Web\MVC\KUrlHelper $Url
	 */
	abstract class KController extends KBaseController implements IController
	{
		/**
		 * The controller action invoker.
		 *  
		 * @var IActionInvoker $_rpropActionInvoker
		 */
		protected $_rpropActionInvoker;
		
		/**
		 * The controller's name
		 * 
		 * @var string $_rpropName
		 */
		protected $_rpropName;
		
		/**
		 * The current HTTP Context.
		 * 
		 * @var KHttpContext $_rpropHttpContext
		 */
		protected $_rpropHttpContext;
		
		/**
		 * The request for which the controller has been created.
		 * 
		 * @var KHttpRequest $_rpropRequest
		 */
		protected $_rpropRequest;
		
		/**
		 * The response to the current action.
		 * 
		 * @var KHttpResponse $_rpropResponse
		 */
		protected $_rpropResponse;
		
		/**
		 * 
		 * @var KRouteCollection $_rpropRouteCollection
		 */
		protected $_propRouteCollection;
		
		/**
		 * The route context object.
		 * 
		 * @var KRouteContext $_rpropRouteContext
		 */
		protected $_rpropRouteContext;
		
		/**
		 * The route data to be used by the controller.
		 * 
		 * @var KRouteData $_rpropRouteData
		 */
		protected $_rpropRouteData;
		
		/**
		 * The URL helper
		 * 
		 * @var KUrlHelper $_propUrl
		 */
		protected $_propUrl;
		
		/**
		 * Construct a new MVC controller
		 * 
		 * @param KRouteContext $context
		 */
		public function __construct(KControllerContext $context)
		{
			parent::__construct($context->RouteContext, $context->ControllerName);
			
			$this->_rpropRouteContext = $context->RouteContext;
			$this->_propUrl = new KUrlHelper($context->RouteContext);
			$this->_rpropRouteData = $context->RouteData;
			$this->_rpropHttpContext = $context->HttpContext;
			$this->_rpropRequest = $context->HttpContext->Request;
			$this->_rpropResponse = $context->HttpContext->Response;
			$this->_propRouteCollection = $context->RouteCollection;
		}
		
		/**
		 * Execute the controller action.
		 * 
		 * (non-PHPdoc)
		 * @see KLF\System\Web\MVC.KBaseController::ExecuteCore()
		 */
		protected function ExecuteCore()
		{
			$actionName = $this->RouteData->GetRequiredString('action');
			$actionInvoker = $this->GetActionInvoker();
			
			$actionContext = new KActionContext($this->ControllerContext, $actionName);
			$actionInvoker->InvokeAction($actionContext);
		}
		
		/**
		 * Returns the factory responsible for creating action invokers.
		 * 
		 * @return \KLF\System\Web\MVC\KDefaultActionFactory
		 */
		protected function GetActionInvoker()
		{
			if (!isset($this->_rpropActionInvoker))
			{
				$this->_rpropActionInvoker = new KControllerActionInvoker(); 
			}
			return $this->_rpropActionInvoker;
		}
		
		/**
		 * Renders a partial view.
		 * 
		 * @param unknown_type $rawParameters
		 */
		protected function PartialView($rawParameters)
		{
		}
		
		/**
		 * Sends a file to the output stream.
		 * 
		 * 
		 */
		protected function File($pawParameters)
		{
			
		}
		
		/**
		 * Render the view
		 * 
		 * @param array $rawParameters
		 * @throws KArgumentException
		 */
		protected function View($rawParameters = array())
		{
			$viewParameters = func_lower_args($rawParameters);
				
			if (isset($viewParameters['view']))
			{
				if (!is_object($viewParameters['view']) || !is_a($viewParameters['view'], 'KLF\System\Web\MVC\IView'))
				{
					throw new KArgumentException("Parameter 'view' must be a valid IView type.");
				}
			}
			if (isset($viewParameters['viewname']))
			{
				if (!is_string($viewParameters['viewname']))
				{
					throw new KArgumentException("Parameter 'viewname' must be a valid view name (string)");
				}
			}
			if (isset($viewParameters['outputtype']))
			{
				if (!is_string($viewParameters['viewname']))
				{
					throw new KArgumentException("Parameter 'outputtype' must be a valid MIME type (string)");
				}
			}
			if (isset($viewParameters['model']))
			{
				if (!is_object($viewParameters['model']) || !is_a($viewParameters['model'], 'KLF\System\Web\MVC\IModel'))
				{
					throw new KArgumentException("Parameter 'view' must be a valid IModel type.");
				}
			}
			$view = KViewFinder::FindView($this->ControllerContext);
			/*
			$viewContext = new KViewContext($this->ControllerContext, 
				$view, 
				$view->ViewData, 
				$view->TempData);
			*/
		}
	}
}